/**
 * 
 */
package edu.gtcfla.km.admin.appmodules.service.impl;

import java.io.Serializable;
import java.util.Calendar;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.vsg.biz.BusinessEntityFactory;
import org.vsg.biz.BusinessOperationException;
import org.vsg.biz.account.Role;
import org.vsg.biz.account.User;
import org.vsg.biz.account.repositories.RoleRepo;
import org.vsg.biz.account.repositories.UserPagingAndSortingRepo;
import org.vsg.common.page.PageItemConverter;
import org.vsg.common.page.PaginationManager;
import org.vsg.search.api.criterion.PaginationCriteria;

import edu.gtcfla.km.admin.appmodules.service.UserService;
import edu.gtcfla.km.admin.appmodules.vo.SysUserFormVO;
import edu.gtcfla.km.admin.appmodules.vo.SysUserListVO;
import edu.gtcfla.km.admin.appmodules.vo.UserRoleAssignedFormVO;
import edu.gtcfla.km.security.api.SubjectManager;

/**
 * @author Bill Vison
 *
 */
public class UserServiceI implements UserService {

	private static final Logger logger = LoggerFactory.getLogger(UserServiceI.class);

	@Resource
	private UserPagingAndSortingRepo<User,String> userRepo;	
	
	@Autowired(required = false)
	private RoleRepo roleRepo;
	
	@Autowired(required = false)
	private SubjectManager subjectManager;

	
	@Autowired(required=false)
	private PaginationManager paginationManager;
	
	private static BusinessEntityFactory entityFactory = BusinessEntityFactory.getInstance();
		

	@Override
	public Page<SysUserListVO> pageUsers(PaginationCriteria criteria) throws BusinessOperationException,
			org.vsg.search.api.page.PaginationException {
		
		String currentUserId = subjectManager.getCurrentAccountId();
		
		Page<User> page = userRepo.findAll(criteria );
		
		PageItemConverter<User , SysUserListVO> 
			itemConverter = new PageItemConverter<User , SysUserListVO>() {
			public SysUserListVO convert( User input ) {
				SysUserListVO newList = new SysUserListVO(input);

				return newList;
			}
		};
	
		Page<SysUserListVO> newPage = (Page<SysUserListVO>) paginationManager.convertItem(page, itemConverter);
		return newPage;

	}

	@Override
	public void addUser(SysUserFormVO formView) throws BusinessOperationException {
		// TODO Auto-generated method stub
		
		User entity = formView.getEntity();
		
		User inputEntity = entity;

		// --- set the object mapping ---
		if (inputEntity.getCode() == null || inputEntity.getCode().equals("")) {
			entity.setCode( null );
		} else {
			entity.setCode( inputEntity.getCode() );
		}
		if (inputEntity.getName() == null || inputEntity.getName().equals("")) {
			entity.setName( null );
		} else {
			entity.setName( inputEntity.getName() );
		}
		if (inputEntity.getEmail() == null || inputEntity.getEmail().equals("")) {
			entity.setEmail( null );
		} else {
			entity.setEmail( inputEntity.getEmail() );
		}
		if (inputEntity.getMobilephone() == null || inputEntity.getMobilephone().equals("")) {
			entity.setMobilephone( null );
		} else {
			entity.setMobilephone( inputEntity.getMobilephone() );
		}		
		if (inputEntity.getOfficephone() == null || inputEntity.getOfficephone().equals("")) {
			entity.setOfficephone( null );
		} else {
			entity.setOfficephone( inputEntity.getOfficephone() );
		}		
		if (inputEntity.getQq() == null || inputEntity.getQq().equals("")) {
			entity.setQq( null );
		} else {
			entity.setQq( inputEntity.getQq() );
		}		
		if (inputEntity.getRemark() == null || inputEntity.getRemark().equals("")) {
			entity.setRemark( null );
		} else {
			entity.setRemark( inputEntity.getQq() );
		}
		
		
		String currentUserId = subjectManager.getCurrentAccountId();
		
		entity.setCreatedUserId( currentUserId );
		entity.setUpdatedUserId( currentUserId );


		Calendar cale = Calendar.getInstance();
		entity.setCreatedDate( cale.getTime() );
		entity.setUpdatedDate( cale.getTime() );		
		
		userRepo.save( entity );

		
	}

	@Override
	public void updateUser(SysUserFormVO formView) throws BusinessOperationException {
		// TODO Auto-generated method stub
		
		User entity = userRepo.findOne( formView.getId() );
		
		User inputEntity = formView.getEntity();
		
		// --- set the object mapping ---
		if (inputEntity.getCode() == null || inputEntity.getCode().equals("")) {
			entity.setCode( null );
		} else {
			entity.setCode( inputEntity.getCode() );
		}
		if (inputEntity.getName() == null || inputEntity.getName().equals("")) {
			entity.setName( null );
		} else {
			entity.setName( inputEntity.getName() );
		}
		if (inputEntity.getEmail() == null || inputEntity.getEmail().equals("")) {
			entity.setEmail( null );
		} else {
			entity.setEmail( inputEntity.getEmail() );
		}
		if (inputEntity.getMobilephone() == null || inputEntity.getMobilephone().equals("")) {
			entity.setMobilephone( null );
		} else {
			entity.setMobilephone( inputEntity.getMobilephone() );
		}		
		if (inputEntity.getOfficephone() == null || inputEntity.getOfficephone().equals("")) {
			entity.setOfficephone( null );
		} else {
			entity.setOfficephone( inputEntity.getOfficephone() );
		}		
		if (inputEntity.getQq() == null || inputEntity.getQq().equals("")) {
			entity.setQq( null );
		} else {
			entity.setQq( inputEntity.getQq() );
		}		
		if (inputEntity.getRemark() == null || inputEntity.getRemark().equals("")) {
			entity.setRemark( null );
		} else {
			entity.setRemark( inputEntity.getQq() );
		}

		String currentUserId = subjectManager.getCurrentAccountId();
		entity.setOwnedUserId(  inputEntity.getOwnedUserId() );
		entity.setUpdatedUserId( currentUserId );
		
		Calendar cale = Calendar.getInstance();
		entity.setUpdatedDate( cale.getTime() );

		
		userRepo.update( entity );		

		
	}

	@Override
	public void deleteUser(SysUserFormVO user) throws BusinessOperationException {
		// TODO Auto-generated method stub
		User userEntity = user.getEntity();
		userRepo.delete( userEntity );
	}

	@Override
	public void markDeleteUser(User user) throws BusinessOperationException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public SysUserFormVO loadUser(Serializable pk) throws BusinessOperationException {
		
		User user = userRepo.findOne( pk.toString() );

		
		SysUserFormVO sUserVo = new SysUserFormVO(user);
		
		Set<String> ids = new LinkedHashSet<String>(); 
		if (user.getCreatedUserId() != null && !user.getCreatedUserId().trim().equals("")) {
			ids.add( user.getCreatedUserId() );
		}
		if (user.getUpdatedUserId() != null && !user.getUpdatedUserId().trim().equals("")) {
			ids.add( user.getUpdatedUserId() );
		}
		if (user.getOwnedUserId() != null && !user.getOwnedUserId().trim().equals("")) {
			ids.add( user.getOwnedUserId() );
		}

		
		Map<String, User> userMap =userRepo.findAllByIds(ids);

		if (user.getCreatedUserId() != null && !user.getCreatedUserId().trim().equals("")) {
			User userEntity = userMap.get( user.getCreatedUserId() );
			if (userEntity != null) {
				sUserVo.setCreatedUser( userEntity.getName() );
			}
		}
		
		if (user.getUpdatedUserId() != null && !user.getUpdatedUserId().trim().equals("")) {
			User userEntity = userMap.get(  user.getUpdatedUserId() );
			if (userEntity != null) {
				sUserVo.setUpdatedUser( userEntity.getName() );
			}
		}
		
		if (user.getOwnedUserId() != null && !user.getOwnedUserId().trim().equals("")) {
			User userEntity = userMap.get(  user.getOwnedUserId() );
			if (userEntity != null) {
				sUserVo.setOwnedUser( userEntity.getName() );
			}			

		}
		

		return sUserVo;
	}

	@Override
	public Collection findUnassociatedRolesByActor(User user)
			throws BusinessOperationException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Set findAssignedRoles(User user) throws BusinessOperationException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void deleteUsers(String[] userIds) throws BusinessOperationException {
		// TODO Auto-generated method stub
		
		for (String id : userIds) {
			User user = entityFactory.create( User.class );
			user.setId( id );
			
			userRepo.delete(user);
		}
	}

	@Override
	public void assignedRoles(String[] roles, User actor)
			throws BusinessOperationException {
		// TODO Auto-generated method stub
		
		Set<String> roleIdSet = new LinkedHashSet<String>();
		for (String roleId : roles) {
			roleIdSet.add( roleId );
		}
		
		// --- assigne new roles ---
		Map<String, Role> rolesMap = roleRepo.findAllByIds( roleIdSet );
		
		userRepo.assignRoles(  actor.getId()  , new LinkedHashSet<Role>( rolesMap.values())  );
		
	}

	@Override
	public UserRoleAssignedFormVO loadRoleAssignedForm(Serializable pk)
			throws BusinessOperationException {
		User entity = userRepo.findOne( pk.toString() );
		
		Set<Role> roles =  roleRepo.findByUserId( entity.getId() );
		
		UserRoleAssignedFormVO roleAssignForm = new UserRoleAssignedFormVO(entity);
		
		List<String> rolIds = new LinkedList<String>();
		for (Role rolId : roles) {
			rolIds.add(  rolId.getId() );
		}
		
		roleAssignForm.setSelectedRoles( rolIds );
		
		return roleAssignForm;
	}
	


}
